package com.lanchetech.service.impl;


import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.lanchetech.bean.request.UrlReq;
import com.lanchetech.bean.response.ContentUploadPictureResp;
import com.lanchetech.bean.response.ResultData;
import com.lanchetech.common.enums.ResultCode;
import com.lanchetech.dao.ReplaceImageMapper;
import com.lanchetech.entity.ReplaceImage;
import com.lanchetech.service.FileService;
import com.lanchetech.service.OSSClientUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;


@Service
public class FileServiceImpl implements FileService {

    @Resource
    private OSSClientUtil ossClient;
    @Autowired
    private ReplaceImageMapper replaceImageMapper;


    @Override
    public ResultData<String> uploadFile(MultipartFile file, String oldImage) {
        ResultData<String> resultData = new ResultData<>();
        try {
            String url = ossClient.uploadFile(file);
            resultData.setValue(url);
            if (StringUtils.isNotBlank(oldImage)) {
                ReplaceImage replaceImage = new ReplaceImage();

                replaceImage.setFromUrl(url);     // 修改之前的图片
                replaceImage.setToUrl(oldImage);  // 修改之后的图片
                replaceImage.setTenantId(0L);
                replaceImageMapper.insert(replaceImage);
            }
            return resultData;
        } catch (Exception e) {
            resultData.setResultCode(ResultCode.FAIL);
            return resultData;
        }
    }


    @Override
    public ResultData<List<String>> uploadMultiFile(MultipartFile[] files) {
        ResultData<List<String>> resultData = new ResultData<>();
        resultData.setValue(new ArrayList<>());
        try {
            for (MultipartFile file : files) {
                String url = ossClient.uploadFile(file);
                resultData.getValue().add(url);
            }
            return resultData;
        } catch (Exception e) {
            e.printStackTrace();
            resultData.setResultCode(ResultCode.FAIL);
            return resultData;
        }
    }

    @Override
    public ContentUploadPictureResp updateContentPicture(MultipartFile file) {
        ContentUploadPictureResp resp = new ContentUploadPictureResp();
        try {
            String imageUrl = ossClient.uploadFile(file);
            String[] data = new String[]{imageUrl};
            resp.setData(data);
            resp.setErrno(0);
            return resp;
        } catch (Exception e) {
            resp.setErrno(1);
            return resp;
        }
    }

    @Override
    public byte[] createQrcode(String content, int width, int height) {
        try {
            if (!StringUtils.isEmpty(content)) {
                ServletOutputStream stream = null;
                ByteArrayOutputStream os = new ByteArrayOutputStream();
                @SuppressWarnings("rawtypes")
                HashMap<EncodeHintType, Comparable> hints = new HashMap<>();
                hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
                // 指定二维码的纠错等级为中级
                hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
                hints.put(EncodeHintType.MARGIN, 0);
                try {
                    QRCodeWriter writer = new QRCodeWriter();
                    BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints);

                    BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix);
                    ImageIO.write(bufferedImage, "png", os);
                    return os.toByteArray();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (stream != null) {
                        stream.flush();
                        stream.close();
                    }
                }

            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String createQrcodeBase64(String content, int width, int height) throws IOException {
        if (!StringUtils.isEmpty(content)) {
            ServletOutputStream stream = null;
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            @SuppressWarnings("rawtypes")
            HashMap<EncodeHintType, Comparable> hints = new HashMap<>();
            hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
            // 指定二维码的纠错等级为中级
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
            hints.put(EncodeHintType.MARGIN, 0);
            try {
                QRCodeWriter writer = new QRCodeWriter();
                BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints);

                BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix);
                ImageIO.write(bufferedImage, "png", os);
                Base64.Encoder base64Encoder = Base64.getEncoder();
                String image = base64Encoder.encodeToString(os.toByteArray());
                return image;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (stream != null) {
                    stream.flush();
                    stream.close();
                }
            }
        }
        return null;
    }

    private String createStringQrcode(String content, int width, int height) throws IOException {
        if (!StringUtils.isEmpty(content)) {
            ServletOutputStream stream = null;
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            @SuppressWarnings("rawtypes")
            HashMap<EncodeHintType, Comparable> hints = new HashMap<>();
            hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
            // 指定二维码的纠错等级为中级
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
            hints.put(EncodeHintType.MARGIN, 0);
            try {
                QRCodeWriter writer = new QRCodeWriter();
                BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints);

                BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix);
                ImageIO.write(bufferedImage, "png", os);
                Base64.Encoder base64Encoder = Base64.getEncoder();
                String image = base64Encoder.encodeToString(os.toByteArray());
                return image;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (stream != null) {
                    stream.flush();
                    stream.close();
                }
            }
        }
        return null;
    }

    @Override
    public ResultData<String> getCommonQrcode(UrlReq url) {
        ResultData<String> resultData = new ResultData<>();
        try {
            String image = createStringQrcode(url.getUrl(), 100, 100);
            resultData.setValue(image);
            return resultData;
        } catch (IOException e) {
            resultData.setResultCode(ResultCode.FAIL);
            return resultData;
        }
    }

}